

local BlockInputField = commonlib.inherit(commonlib.ToolBase);

BlockInputField:Property("ClassName", "BlockInputField");
BlockInputField:Property("Blockly");         -- 所属blockly
BlockInputField:Property("Block");           -- 所属block
BlockInputField:Property("Name");            -- 名称
BlockInputField:Property("Type");            -- 类型  block input_value field
BlockInputField:Property("Option");          -- 选项
BlockInputField:Property("InputFieldContainer");                  -- 所属输入字段容器
BlockInputField:Property("MouseMoving", false, "IsMouseMoving");  -- 是否移动鼠标 
BlockInputField:Property("CanEdit", false, "IsCanEdit");          -- 是否可编辑

local EDGE_EXTENSION_PX = 0;                                      -- 边缘扩展像素
BlockInputField.FIELD_MAX_WIDTH_UNIT_COUNT = 120;                 -- 字段最大宽度
BlockInputField.FIELD_SPACE_WIDTH_UNIT_COUNT = 2;                 -- 空白间隙宽度
BlockInputField.FIELD_SPACE_HEIGHT_UNIT_COUNT = 2;                -- 空白间隙高度
BlockInputField.FIELD_TEXT_HEIGHT_UNIT_COUNT = 6;                 -- 文本字段高度
BlockInputField.FIELD_INPUT_HEIGHT_UNIT_COUNT = 8;                -- 输入字段高度
BlockInputField.CONNECTION_HEIGHT_UNIT_COUNT = 2;                 -- 上下连接高度
BlockInputField.CONNECTION_REGION_HEIGHT_UNIT_COUNT = 14;         -- 连接区域高度
BlockInputField.CONNECTION_REGION_WIDTH_UNIT_COUNT = 12;          -- 连接区域高度
BlockInputField.START_CONNECTION_HEIGHT_UNIT_COUNT = 4;           -- 开始连接高度
BlockInputField.OUTPUT_CONNECTION_HEIGHT_UNIT_COUNT = 1;          -- 输出链接高度
BlockInputField.STATEMENT_WIDTH_UNIT_COUNT = 4;                   -- 语句左侧宽度
BlockInputField.FONT_SIZE = 14;                                   -- 字体大小
BlockInputField.FONT_COLOR = 0xff;                                -- 字体颜色

function BlockInputField:ctor()
    self.__total_width_unit_count__, self.__total_height_unit_count__ = 0, 0;
    self.__total_width__, self.__total_height__ = 0, 0;
    self.__max_width_unit_count__, self.__max_height_unit_count__ = 0, 0;
    self.__max_width__, self.__max_height__ = 0, 0;
    self.__width_unit_count__, self.__height_unit_count__ = 0, 0;
    self.__width__, self.__height__ = 0, 0;
    self.__left_unit_count__, self.__top_unit_count__ = 0, 0;
    self.__left__, self.__top__ = 0, 0;
end

function BlockInputField:Init(block, opt)
    opt = opt or {};

    self:SetOption(opt);
    self:SetName(opt.name);
    self:SetType(opt.type);
    self:SetBlock(block);
    self:SetBlockly(self:GetBlock():GetBlockly());
  
    return self;
end

function BlockInputField:SaveToXmlNode()
end

function BlockInputField:LoadFromXmlNode()
end


function BlockInputField:GetUnitSize()
    return self:GetBlockly():GetUnitSize();
end

function BlockInputField:GetOutputBlock()
    local block = self:GetBlock();
    local connection = block.__output_connection__ and block.__output_connection__:GetConnection();
    return connection and connection:GetBlock();
end

function BlockInputField:GetNextBlock()
    local block = self:GetBlock();
    local connection = block.__next_connection__ and block.__next_connection__:GetConnection();
    return connection and connection:GetBlock();
end

function BlockInputField:GetPrevBlock()
    local block = self:GetBlock();
    local connection = block.__previous_connection__ and block.__previous_connection__:GetConnection();
    return connection and connection:GetBlock();
end

function BlockInputField:GetLastNextBlock()
    local prevBlock, nextBlock = self:GetBlock(), self:GetNextBlock();
    while (nextBlock) do 
        prevBlock = nextBlock;
        nextBlock = prevBlock:GetNextBlock();
    end
    return prevBlock;
end

function BlockInputField:GetTopBlock()
    local prevBlock, nextBlock = self:GetPrevBlock() or self:GetOutputBlock(), self:GetBlock();
    while (prevBlock) do 
        nextBlock = prevBlock;
        prevBlock = nextBlock:GetPrevBlock() or nextBlock:GetOutputBlock();
    end
    return nextBlock;
end

function BlockInputField:ConnectionBlock(block)
    return false;
end

function BlockInputField:SetTotalWidthHeightUnitCount(widthUnitCount, heightUnitCount)
    local UnitSize = self:GetUnitSize();
    self.__total_width_unit_count__, self.__total_height_unit_count__ = widthUnitCount or self.__total_width_unit_count__, heightUnitCount or self.__total_height_unit_count__;
    self.__total_width__, self.__total_height__ = self.__total_width_unit_count__ * UnitSize, self.__total_height_unit_count__ * UnitSize;
    -- if (self:GetType() ~= "__shadow_block__") then
    --     commonlib.print_format("%s __total_width_unit_count__ = %s __total_height_unit_count__ = %s", self:GetType(), self.__total_width_unit_count__, self.__total_height_unit_count__);
    -- end
end

function BlockInputField:GetTotalWidthHeight()
    return self.__total_width__, self.__total_height__;
end

function BlockInputField:GetTotalWidthHeightUnitCount()
    return self.__total_width_unit_count__, self.__total_height_unit_count__;
end

function BlockInputField:SetMaxWidthHeightUnitCount(widthUnitCount, heightUnitCount)
    local UnitSize = self:GetUnitSize();
    self.__max_width_unit_count__, self.__max_height_unit_count__ = widthUnitCount or self.__max_width_unit_count__, heightUnitCount or self.__max_height_unit_count__;
    self.__max_width__, self.__max_height__ = self.__max_width_unit_count__ * UnitSize, self.__max_height_unit_count__ * UnitSize;
end

function BlockInputField:GetMaxWidthHeight()
    return self.__max_width__, self.__max_height__;
end

function BlockInputField:GetMaxWidthHeightUnitCount()
    return self.__max_width_unit_count__, self.__max_height_unit_count__;
end

function BlockInputField:SetWidthHeightUnitCount(widthUnitCount, heightUnitCount)
    local UnitSize = self:GetUnitSize();
    self.__width_unit_count__, self.__height_unit_count__ = widthUnitCount or self.__width_unit_count__, heightUnitCount or self.__height_unit_count__;
    self.__width__, self.__height__ = self.__width_unit_count__ * UnitSize, self.__height_unit_count__ * UnitSize;
    -- if (self:GetType() ~= "__shadow_block__") then
    --     commonlib.print_format("%s __width_unit_count__ = %s __height_unit_count__ = %s", self:GetType(), self.__width_unit_count__, self.__height_unit_count__);
    -- end
    self:OnSizeChange();
end

function BlockInputField:GetWidthHeight()
    return self.__width__, self.__height__;
end

function BlockInputField:GetWidthHeightUnitCount()
    return self.__width_unit_count__, self.__height_unit_count__;
end

function BlockInputField:SetLeftTopUnitCount(leftUnitCount, topUnitCount)
    local UnitSize = self:GetUnitSize();
    self.__left_unit_count__, self.__top_unit_count__ = leftUnitCount or self.__left_unit_count__, topUnitCount or self.__top_unit_count__;
    self.__left__, self.__top__ = self.__left_unit_count__ * UnitSize, self.__top_unit_count__ * UnitSize;
    -- if (self:GetType() ~= "__shadow_block__") then
    --     commonlib.print_format("%s __left_unit_count__ = %s __top_unit_count__ = %s", self:GetType(), self.__left_unit_count__, self.__top_unit_count__);
    -- end
    self:OnSizeChange();
end

function BlockInputField:GetLeftTop()
    return self.__left__, self.__top__;
end

function BlockInputField:GetLeftTopUnitCount()
    return self.__left_unit_count__, self.__top_unit_count__;
end

function BlockInputField:GetBorderRadius()
    return 0;
end

function BlockInputField:OnSizeChange()
end

function BlockInputField:UpdateWidthHeightUnitCount()
    return 0, 0, 0, 0, 0, 0;  -- 最大宽高, 元素宽高, 元素总宽高
end

function BlockInputField:UpdateLeftTopUnitCount()
    return 0, 0;
end

function BlockInputField:UpdateLayout()
end

function BlockInputField:GetMouseUI(x, y)
    local maxWidth, maxHeight = self:GetMaxWidthHeight();
    local left, top = self:GetLeftTop();
    if (x < left or x > (left + maxWidth) or y < top or y > (top + maxHeight)) then return end
    local block = self:GetBlock();
    return block:IsToolBoxBlock() and block or self;
end

function BlockInputField:CaptureMouse()
    local blockly = self:GetBlockly();
    blockly:SetMouseCaptureUI(self);
    blockly:CaptureMouse();
end

function BlockInputField:ReleaseMouse()
    local blockly = self:GetBlockly();
    blockly:SetMouseCaptureUI(nil);
    blockly:ReleaseMouse();
end

function BlockInputField:OnMouseDown(event)
    self:GetBlock():OnMouseDown(event);
end

function BlockInputField:OnMouseMove(event)
    self:GetBlock():OnMouseMove(event);
end

function BlockInputField:OnMouseUp(event)
    local block = self:GetBlock();
    if (not block:IsDragging()) then
        if (event:IsLeftButton()) then
            self:OnClick();
        else
            self:OnContextMenu();
        end
    end
    block:OnMouseUp(event);
end

function BlockInputField:OnClick(event)
    if (not self:IsCanEdit()) then return end 
    self:GetBlockly():GetEditor():Show(self);
end

function BlockInputField:OnContextMenu()
end

function BlockInputField:ToColor(color)
    return self:GetBlockly():ToColorFromString(color);
end

function BlockInputField:SetBrushColor(color)
    self:GetBlockly():SetBrushColor(color);
end

function BlockInputField:SetFontColor()
end

function BlockInputField:RenderContent()
end

function BlockInputField:Render()
    local maxWidthUnitCount, maxHeightUnitCount = self:GetMaxWidthHeightUnitCount();
    local widthUnitCount, heightUnitCount = self:GetWidthHeightUnitCount();
    local leftUnitCount, topUnitCount = self:GetLeftTopUnitCount();
    local UnitSize = self:GetUnitSize();
    local tx = leftUnitCount * UnitSize;
    local ty = (topUnitCount + (maxHeightUnitCount - heightUnitCount) / 2) * UnitSize;
    local blockly = self:GetBlockly();
    blockly:Translate(tx, ty);
    self:RenderContent();
    blockly:Translate(-tx, -ty);
end

function BlockInputField:IsEditing()
    return self:GetBlockly():GetEditor():GetInputField() == self;
end

function BlockInputField:GetTextWidthUnitCount(text)
    local blockly = self:GetBlockly();
    local UnitSize = blockly:GetUnitSize();
    local width = blockly:GetTextWidth(text, self.FONT_SIZE);
    return math.floor(width / UnitSize);
end

function BlockInputField:GetTextByWidth(text, widthUnitCount)
    local blockly = self:GetBlockly();
    local UnitSize = blockly:GetUnitSize();
    local text = blockly:GetTextByWidth(text, widthUnitCount * UnitSize - 21, self.FONT_SIZE);
    return text .. "...";
end

function BlockInputField:DrawText(text, widthUnitCount, heightUnitCount, offsetXUnitCount, offsetYUnitCount, fontSize, fontColor)
    local blockly = self:GetBlockly();
    local UnitSize = blockly:GetUnitSize();
    offsetXUnitCount, offsetYUnitCount = offsetXUnitCount or 0, offsetYUnitCount or 0;
    blockly:SetFontSize(fontSize or self.FONT_SIZE);
    blockly:SetFontStringColor(fontColor or self.FONT_COLOR);
    blockly:DrawText(offsetXUnitCount * UnitSize, offsetYUnitCount * UnitSize, widthUnitCount * UnitSize, heightUnitCount * UnitSize, text or "", "center");
end

function BlockInputField:DrawStartConnection(widthUnitCount, offsetXUnitCount, offsetYUnitCount)
    local blockly = self:GetBlockly();
    local UnitSize = blockly:GetUnitSize();
    if (offsetXUnitCount or offsetYUnitCount) then
        blockly:Translate(offsetXUnitCount * UnitSize, offsetYUnitCount * UnitSize);
    end

    blockly:Save();
    blockly:DrawRectangle(0, 0, widthUnitCount * UnitSize, 4 * UnitSize);
    blockly:Clip();
    -- 绘制上半圆
    blockly:DrawArc(8 * UnitSize, 6 * UnitSize, 10 * UnitSize, 180, 360);
    -- 绘制下边
    blockly:DrawRectangle(0, 2 * UnitSize, (widthUnitCount - 1) * UnitSize, UnitSize);
    blockly:DrawCircle((widthUnitCount - 1) * UnitSize, 3 * UnitSize, UnitSize);
    blockly:DrawRectangle(0, 3 * UnitSize, widthUnitCount * UnitSize, UnitSize);
    blockly:Restore();

    if (offsetXUnitCount or offsetYUnitCount) then
        blockly:Translate(-offsetXUnitCount * UnitSize, -offsetYUnitCount * UnitSize);
    end
end
    
-- 绘制上边及凹陷部分 占据高度 2 * UnitSize
function BlockInputField:DrawPrevConnection(widthUnitCount, offsetXUnitCount, offsetYUnitCount, isDrawOutline)
    local blockly = self:GetBlockly();
    local UnitSize = blockly:GetUnitSize();
    if (offsetXUnitCount or offsetYUnitCount) then
        blockly:Translate(offsetXUnitCount * UnitSize, offsetYUnitCount * UnitSize);
    end
    blockly:DrawArc(UnitSize, UnitSize, UnitSize, 180, 270, true, false);
    blockly:DrawRectangle(UnitSize, 0, 3 * UnitSize, UnitSize, true, false);
    blockly:DrawRectangle(0, UnitSize - EDGE_EXTENSION_PX / 2, 4 * UnitSize, UnitSize + EDGE_EXTENSION_PX, true, false);
    blockly:DrawTriangle(4 * UnitSize, 0, 4 * UnitSize, 2 * UnitSize, 6 * UnitSize, 2 * UnitSize, true, false);
    blockly:DrawTriangle(10 * UnitSize, 2 * UnitSize, 12 * UnitSize, 2 * UnitSize, 12 * UnitSize, 0, true, false);
    blockly:DrawRectangle(12 * UnitSize, 0, (widthUnitCount - 13) * UnitSize, UnitSize, true, false);
    blockly:DrawRectangle(12 * UnitSize, UnitSize - EDGE_EXTENSION_PX / 2, (widthUnitCount - 12) * UnitSize, UnitSize + EDGE_EXTENSION_PX, true, false);
    blockly:DrawArc((widthUnitCount - 1) * UnitSize, UnitSize, UnitSize, 270, 360, true, false);
    if (isDrawOutline) then
        blockly:DrawLine(0, UnitSize, 0, 2 * UnitSize);
        blockly:DrawLine(widthUnitCount * UnitSize, UnitSize, widthUnitCount * UnitSize, 2 * UnitSize);
        blockly:DrawArc(UnitSize, UnitSize, UnitSize, 180, 270, false, true);
        blockly:DrawArc((widthUnitCount - 1) * UnitSize, UnitSize, UnitSize, 270, 360, false, true);
        blockly:DrawLine(1 * UnitSize, 0 * UnitSize, 4 * UnitSize, 0 * UnitSize);
        blockly:DrawLine(4 * UnitSize, 0 * UnitSize, 6 * UnitSize, 2 * UnitSize);
        blockly:DrawLine(6 * UnitSize, 2 * UnitSize, 10 * UnitSize, 2 * UnitSize);
        blockly:DrawLine(10 * UnitSize, 2 * UnitSize, 12 * UnitSize, 0 * UnitSize);
        blockly:DrawLine(12 * UnitSize, 0 * UnitSize, (widthUnitCount - 1) * UnitSize, 0 * UnitSize);
    end
    if (offsetXUnitCount or offsetYUnitCount) then
        blockly:Translate(-offsetXUnitCount * UnitSize, -offsetYUnitCount * UnitSize);
    end
end
    
-- 绘制下边及突出部分 占据高度 4 * UnitSize
function BlockInputField:DrawNextConnection(widthUnitCount, offsetXUnitCount, offsetYUnitCount, isDrawOutline)
    local blockly = self:GetBlockly();
    local UnitSize = blockly:GetUnitSize();
    if (offsetXUnitCount or offsetYUnitCount) then
        blockly:Translate(offsetXUnitCount * UnitSize, offsetYUnitCount * UnitSize);
    end

    blockly:DrawRectangle(0, 0 - EDGE_EXTENSION_PX / 2, widthUnitCount * UnitSize, UnitSize + EDGE_EXTENSION_PX, true, false);   -- 多绘制一个单元向上
    blockly:DrawArc(UnitSize, UnitSize, UnitSize, 90, 180, true, false);
    blockly:DrawArc((widthUnitCount - 1) * UnitSize, UnitSize, UnitSize, 0, 90, true, false);
    blockly:DrawRectangle(UnitSize, UnitSize, (widthUnitCount - 2) * UnitSize, UnitSize, true, false);
    blockly:DrawTriangle(4 * UnitSize, 2 * UnitSize, 6 * UnitSize, 2 * UnitSize, 6 * UnitSize, 4 * UnitSize, true, false);
    blockly:DrawRectangle(6 * UnitSize, 2 * UnitSize, 4 * UnitSize, 2 * UnitSize, true, false);
    blockly:DrawTriangle(10 * UnitSize, 2 * UnitSize, 10 * UnitSize, 4 * UnitSize, 12 * UnitSize, 2 * UnitSize, true, false);
    if (isDrawOutline) then
        blockly:DrawLine(0, 0, 0, UnitSize);
        blockly:DrawLine(widthUnitCount * UnitSize, 0, widthUnitCount * UnitSize, UnitSize);
        blockly:DrawArc(UnitSize, UnitSize, UnitSize, 90, 180, false, true);
        blockly:DrawArc((widthUnitCount - 1) * UnitSize, UnitSize, UnitSize, 0, 90, false, true);
        blockly:DrawLine(1 * UnitSize, 2 * UnitSize, 4 * UnitSize, 2 * UnitSize);
        blockly:DrawLine(4 * UnitSize, 2 * UnitSize, 6 * UnitSize, 4 * UnitSize);
        blockly:DrawLine(6 * UnitSize, 4 * UnitSize, 10 * UnitSize, 4 * UnitSize);
        blockly:DrawLine(10 * UnitSize, 4 * UnitSize, 12 * UnitSize, 2 * UnitSize);
        blockly:DrawLine(12 * UnitSize, 2 * UnitSize, (widthUnitCount - 1) * UnitSize, 2 * UnitSize);
    end

    if (offsetXUnitCount or offsetYUnitCount) then
        blockly:Translate(-offsetXUnitCount * UnitSize, -offsetYUnitCount * UnitSize);
    end
end
    
-- 绘制输出块
function BlockInputField:DrawOutput(widthUnitCount, heightUnitCount, offsetXUnitCount, offsetYUnitCount)
    local blockly = self:GetBlockly();
    local UnitSize = blockly:GetUnitSize();
    if (offsetXUnitCount or offsetYUnitCount) then
        blockly:Translate(offsetXUnitCount * UnitSize, offsetYUnitCount * UnitSize);
    end

    blockly:DrawCircle(UnitSize, UnitSize, UnitSize);
    blockly:DrawCircle((widthUnitCount - 1) * UnitSize, UnitSize, UnitSize);
    blockly:DrawRectangle(UnitSize, 0, (widthUnitCount - 2) * UnitSize, UnitSize);
    blockly:DrawRectangle(0, UnitSize, widthUnitCount * UnitSize, (heightUnitCount - 2) * UnitSize);
    blockly:DrawCircle(UnitSize, (heightUnitCount - 1) * UnitSize, UnitSize);
    blockly:DrawCircle((widthUnitCount - 1) * UnitSize, (heightUnitCount - 1) * UnitSize, UnitSize);
    blockly:DrawRectangle(UnitSize, (heightUnitCount - 1) * UnitSize, (widthUnitCount - 2) * UnitSize, UnitSize);

    if (offsetXUnitCount or offsetYUnitCount) then
        blockly:Translate(-offsetXUnitCount * UnitSize, -offsetYUnitCount * UnitSize);
    end
end
    
-- 绘制矩形
function BlockInputField:DrawRectangle(widthUnitCount, heightUnitCount, offsetXUnitCount, offsetYUnitCount, isDrawOutline)
    local blockly = self:GetBlockly();
    local UnitSize = blockly:GetUnitSize();
    if (offsetXUnitCount or offsetYUnitCount) then
        blockly:Translate(offsetXUnitCount * UnitSize, offsetYUnitCount * UnitSize);
    end
    blockly:DrawRectangle(0, 0, widthUnitCount * UnitSize, heightUnitCount * UnitSize);
    if (isDrawOutline) then
        blockly:DrawLine(0, 0, 0, heightUnitCount * UnitSize);
        blockly:DrawLine(widthUnitCount * UnitSize, 0, widthUnitCount * UnitSize, heightUnitCount * UnitSize);
    end
    if (offsetXUnitCount or offsetYUnitCount) then
        blockly:Translate(-offsetXUnitCount * UnitSize, -offsetYUnitCount * UnitSize);
    end
end
    
-- 绘制输入语句
function BlockInputField:DrawInputStatement(widthUnitCount, heightUnitCount, offsetXUnitCount, offsetYUnitCount, isDrawOutline)
    local blockly = self:GetBlockly();
    local UnitSize = blockly:GetUnitSize();
    if (offsetXUnitCount or offsetYUnitCount) then
        blockly:Translate(offsetXUnitCount * UnitSize, offsetYUnitCount * UnitSize);
    end
    widthUnitCount = widthUnitCount or 20;
    heightUnitCount = heightUnitCount or 16;
    blockly:DrawRectangle(0, 0, widthUnitCount * UnitSize, UnitSize, true, false);
    blockly:DrawRectangle(0, UnitSize, (widthUnitCount - 1) * UnitSize, UnitSize, true, false);
    blockly:DrawArc((widthUnitCount - 1) * UnitSize, UnitSize, UnitSize, 0, 90, true, false);
    blockly:DrawTriangle(8 * UnitSize, 2 * UnitSize, 10 * UnitSize, 2 * UnitSize, 10 * UnitSize, 4 * UnitSize, true, false);
    blockly:DrawRectangle(10 * UnitSize, 2 * UnitSize, 4 * UnitSize, 2 * UnitSize, true, false);
    blockly:DrawTriangle(14 * UnitSize, 2 * UnitSize, 14 * UnitSize, 4 * UnitSize, 16 * UnitSize, 2 * UnitSize, true, false);
    if (isDrawOutline) then 
        blockly:DrawArc((widthUnitCount - 1) * UnitSize, UnitSize, UnitSize, 0, 90, false, true);
        blockly:DrawLine(16 * UnitSize, 2 * UnitSize, (widthUnitCount - 1) * UnitSize, 2 * UnitSize);
        blockly:DrawLine(14 * UnitSize, 4 * UnitSize, 16 * UnitSize, 2 * UnitSize);
        blockly:DrawLine(10 * UnitSize, 4 * UnitSize, 14 * UnitSize, 4 * UnitSize);
        blockly:DrawLine(8 * UnitSize, 2 * UnitSize, 10 * UnitSize, 4 * UnitSize);
        blockly:DrawLine(5 * UnitSize, 2 * UnitSize, 8 * UnitSize, 2 * UnitSize);
        blockly:DrawLine(widthUnitCount * UnitSize, 0, widthUnitCount * UnitSize, UnitSize);
    end
    -- 中间 12
    -- 内弧
    blockly:MoveTo(4 * UnitSize, 2 * UnitSize);
    blockly:DrawArc(5 * UnitSize, 3 * UnitSize, UnitSize, 180, 270, false, false);
    blockly:Fill();
    if (isDrawOutline) then
        blockly:MoveTo(4 * UnitSize, 2 * UnitSize);
        blockly:DrawArc(5 * UnitSize, 3 * UnitSize, UnitSize, 180, 270, false, false);
        blockly:Stroke();
    end
    -- 中间矩形
    blockly:DrawRectangle(0, 0, 4 * UnitSize, heightUnitCount * UnitSize, true, false);
    blockly:Translate(0, (heightUnitCount -2) * UnitSize);
    -- 内弧
    blockly:MoveTo(4 * UnitSize, 0);
    blockly:DrawArc(5 * UnitSize, -UnitSize, UnitSize, 90, 180, false, false);
    blockly:Fill();
    if (isDrawOutline) then
        blockly:MoveTo(4 * UnitSize, 0);
        blockly:DrawArc(5 * UnitSize, -UnitSize, UnitSize, 90, 180, false, false);
        blockly:Stroke();
    end
    -- 下2格
    blockly:DrawRectangle(0, 0, 8 * UnitSize, 2 * UnitSize, true, false);
    blockly:DrawTriangle(8 * UnitSize, 0, 8 * UnitSize, 2 * UnitSize, 10 * UnitSize, 2 * UnitSize, true, false);
    blockly:DrawTriangle(14 * UnitSize, 2 * UnitSize, 16 * UnitSize, 2 * UnitSize, 16 * UnitSize, 0, true, false);
    blockly:DrawRectangle(16 * UnitSize, 0, (widthUnitCount - 17) * UnitSize, UnitSize, true, false);
    blockly:DrawRectangle(16 * UnitSize, UnitSize, (widthUnitCount - 16) * UnitSize, UnitSize, true, false);
    blockly:DrawArc((widthUnitCount - 1) * UnitSize, UnitSize, UnitSize, 270, 360, true, false);
    if (isDrawOutline) then 
        blockly:DrawArc((widthUnitCount - 1) * UnitSize, UnitSize, UnitSize, 270, 360, false, true);
        blockly:DrawLine(16 * UnitSize, 0 * UnitSize, (widthUnitCount - 1) * UnitSize, 0 * UnitSize);
        blockly:DrawLine(14 * UnitSize, 2 * UnitSize, 16 * UnitSize, 0 * UnitSize);
        blockly:DrawLine(10 * UnitSize, 2 * UnitSize, 14 * UnitSize, 2 * UnitSize);
        blockly:DrawLine(8 * UnitSize, 0 * UnitSize, 10 * UnitSize, 2 * UnitSize);
        blockly:DrawLine(5 * UnitSize, 0 * UnitSize, 8 * UnitSize, 0 * UnitSize);
        blockly:DrawLine(widthUnitCount * UnitSize, UnitSize, widthUnitCount * UnitSize, 2 * UnitSize);
    end
    blockly:Translate(0, -(heightUnitCount -2) * UnitSize);
    if (isDrawOutline) then
        blockly:DrawLine(0, 0, 0, (heightUnitCount) * UnitSize);
        blockly:DrawLine(4 * UnitSize, 3 * UnitSize, 4 * UnitSize, (heightUnitCount - 3) * UnitSize);
    end
    if (offsetXUnitCount or offsetYUnitCount) then
        blockly:Translate(-offsetXUnitCount * UnitSize, -offsetYUnitCount * UnitSize);
    end
end
    
-- 绘制输入值
function BlockInputField:DrawInputValue(widthUnitCount, heightUnitCount, offsetXUnitCount, offsetYUnitCount)
    local blockly = self:GetBlockly();
    local UnitSize = blockly:GetUnitSize();
    if (offsetXUnitCount or offsetYUnitCount) then
        blockly:Translate(offsetXUnitCount * UnitSize, offsetYUnitCount * UnitSize);
    end
    
    widthUnitCount = widthUnitCount or 8;
    heightUnitCount = heightUnitCount or 8;

    local radiusUnitCount = heightUnitCount / 2;
    blockly:DrawCircle(radiusUnitCount * UnitSize, radiusUnitCount * UnitSize, radiusUnitCount * UnitSize);
    blockly:DrawCircle((widthUnitCount - radiusUnitCount) * UnitSize, radiusUnitCount * UnitSize, radiusUnitCount * UnitSize);
    blockly:DrawRectangle(radiusUnitCount * UnitSize, 0, (widthUnitCount - heightUnitCount) * UnitSize, heightUnitCount * UnitSize);

    if (offsetXUnitCount or offsetYUnitCount) then
        blockly:Translate(-offsetXUnitCount * UnitSize, -offsetYUnitCount * UnitSize);
    end
end

-- 绘制输出块
function BlockInputField:DrawOutputBlock(widthUnitCount, heightUnitCount, offsetXUnitCount, offsetYUnitCount, isDrawOutline)
    local blockly = self:GetBlockly();
    local UnitSize = blockly:GetUnitSize();
    if (offsetXUnitCount or offsetYUnitCount) then
        blockly:Translate(offsetXUnitCount * UnitSize, offsetYUnitCount * UnitSize);
    end
    widthUnitCount = widthUnitCount or 8;
    heightUnitCount = heightUnitCount or 8;
    local radiusUnitCount = heightUnitCount / 2;
    blockly:DrawArc(radiusUnitCount * UnitSize, radiusUnitCount * UnitSize, radiusUnitCount * UnitSize, 90, 270, true, false);
    blockly:DrawArc((widthUnitCount - radiusUnitCount) * UnitSize, radiusUnitCount * UnitSize, radiusUnitCount * UnitSize, 270, 450, true, false);
    blockly:DrawRectangle(radiusUnitCount * UnitSize, 0, (widthUnitCount - heightUnitCount) * UnitSize, heightUnitCount * UnitSize, true, false);
    if (isDrawOutline) then
        blockly:DrawArc(radiusUnitCount * UnitSize, radiusUnitCount * UnitSize, radiusUnitCount * UnitSize, 90, 270, false, true);
        blockly:DrawArc((widthUnitCount - radiusUnitCount) * UnitSize, radiusUnitCount * UnitSize, radiusUnitCount * UnitSize, 270, 450, false, true);
        blockly:DrawLine(radiusUnitCount * UnitSize, 0, (widthUnitCount - radiusUnitCount) * UnitSize, 0);
        blockly:DrawLine(radiusUnitCount * UnitSize, heightUnitCount * UnitSize, (widthUnitCount - radiusUnitCount) * UnitSize, heightUnitCount * UnitSize);
    end
    if (offsetXUnitCount or offsetYUnitCount) then
        blockly:Translate(-offsetXUnitCount * UnitSize, -offsetYUnitCount * UnitSize);
    end
end

-- 绘制阴影语句块
function BlockInputField:DrawShadowStatementBlock(widthUnitCount, heightUnitCount, offsetXUnitCount, offsetYUnitCount)
    local blockly = self:GetBlockly();
    local UnitSize = blockly:GetUnitSize();
    if (offsetXUnitCount or offsetYUnitCount) then
        blockly:Translate(offsetXUnitCount * UnitSize, offsetYUnitCount * UnitSize);
    end
    widthUnitCount = widthUnitCount or 16;
    heightUnitCount = heightUnitCount or 12;

    -- 上边
    blockly:DrawArc(UnitSize, UnitSize, UnitSize, 180, 270, true, false);
    blockly:DrawRectangle(UnitSize, 0, 3 * UnitSize, UnitSize, true, false);
    blockly:DrawRectangle(0, UnitSize, 4 * UnitSize, UnitSize, true, false);
    blockly:DrawTriangle(4 * UnitSize, 0, 4 * UnitSize, 2 * UnitSize, 6 * UnitSize, 2 * UnitSize, true, false);
    blockly:DrawTriangle(10 * UnitSize, 2 * UnitSize, 12 * UnitSize, 2 * UnitSize, 12 * UnitSize, 0, true, false);
    blockly:DrawRectangle(12 * UnitSize, 0, (widthUnitCount - 13) * UnitSize, UnitSize, true, false);
    blockly:DrawRectangle(12 * UnitSize, UnitSize, (widthUnitCount - 12) * UnitSize, UnitSize, true, false);
    blockly:DrawArc((widthUnitCount - 1) * UnitSize, UnitSize, UnitSize, 270, 360, true, false);

    -- 中间 矩形
    blockly:Translate(0, 2 * UnitSize);
    blockly:DrawRectangle(0, 0, widthUnitCount * UnitSize, (heightUnitCount - 4) * UnitSize);

    -- 下边
    blockly:Translate(0, (heightUnitCount - 4) * UnitSize);
    blockly:DrawRectangle(0, 0, widthUnitCount * UnitSize, UnitSize);
    blockly:DrawArc(UnitSize, UnitSize, UnitSize, 90, 180, true, false);
    blockly:DrawArc((widthUnitCount - 1) * UnitSize, UnitSize, UnitSize, 0, 90, true, false);
    blockly:DrawRectangle(UnitSize, UnitSize, (widthUnitCount - 2) * UnitSize, UnitSize);
    blockly:DrawTriangle(4 * UnitSize, 2 * UnitSize, 6 * UnitSize, 2 * UnitSize, 6 * UnitSize, 4 * UnitSize);
    blockly:DrawRectangle(6 * UnitSize, 2 * UnitSize, 4 * UnitSize, 2 * UnitSize);
    blockly:DrawTriangle(10 * UnitSize, 2 * UnitSize, 10 * UnitSize, 4 * UnitSize, 12 * UnitSize, 2 * UnitSize);

    blockly:Translate(0, -(heightUnitCount - 2) * UnitSize);

    if (offsetXUnitCount or offsetYUnitCount) then
        blockly:Translate(-offsetXUnitCount * UnitSize, -offsetYUnitCount * UnitSize);
    end
end

function BlockInputField:Translate(XUnitCount, YUnitCount)
    if (not XUnitCount or not YUnitCount) then return end 
    local blockly = self:GetBlockly();
    local UnitSize = blockly:GetUnitSize();
    blockly:Translate(XUnitCount * UnitSize, YUnitCount * UnitSize);
end

return BlockInputField;

-- https://github.com/LLK/scratch-blocks/wiki/Design#grid